package com.google.lazyloading;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;

import javax.persistence.EntityManager;

import com.google.AbstractBaseComparision;
import com.google.lazyloading.entity.LazyBook;
import com.google.lazyloading.entity.LazyShelf;
import com.google.lazyloading.entity.NormalShelf;
import com.google.utility.JpaUtil;
import com.google.utility.TimeMachine;

public class LazyLoadingComparision extends AbstractBaseComparision {

	static public long applyLazyLoading() {
		System.out.println("Start lazy loading");
		TimeMachine timeMachine = new TimeMachine();
		timeMachine.start();

		EntityManager entityManager = createEntityManager();
		LazyShelf lazyShelf = entityManager.find(LazyShelf.class, 1L);
		List<LazyBook> books = lazyShelf.getBooks();
		books.get(0);
		JpaUtil.closeEntityManager(entityManager);
		long period = timeMachine.finish();

		System.out.println("Size of shelf: " + books.size() + " books");
		return period;
	}

	static public long notApplyLazyLoading() {
		System.out.println("Start normal loading");
		TimeMachine timeMachine = new TimeMachine();
		timeMachine.start();

		EntityManager entityManager = createEntityManager();
		NormalShelf shelf = entityManager.find(NormalShelf.class, 1L);
		JpaUtil.closeEntityManager(entityManager);
		long period = timeMachine.finish();

		System.out.println("Size of shelf: " + shelf.getBooks().size()
				+ " books");
		return period;
	}

	static public void test100Books() {
		import100Books();
		compareLazyLoading();
	}

	public static void main(String[] args) {
		// compareLazyLoading();
		import100Books();
	}

	private static File getScriptFile(String filename) {
		File file = null;
		URL url = LazyLoadingComparision.class.getResource("/"
				+ LazyLoadingComparision.class.getPackage().getName()
						.replace('.', '/') + "/" + filename);
		try {
			file = new File(url.toURI());
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}
		return file;
	}

	private static void import100Books() {
		File script = getScriptFile("run_100_books.sh");
		runScript(script);
	}

	private static void runScript(File script) {
		File dir = script.getParentFile();
		ProcessBuilder pb = new ProcessBuilder(script.getPath());
		pb.directory(dir);
		Process process;
		try {
			process = pb.start();
			process.waitFor();
		} catch (IOException | InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	private static void compareLazyLoading() {
		long lazyPeriod = applyLazyLoading();
		long nonLazyPeriod = notApplyLazyLoading();
		evaluateLazyResult(lazyPeriod, nonLazyPeriod);
	}

	private static void evaluateLazyResult(long lazyPeriod, long nonLazyPeriod) {
		System.out.println("Lazy loading! Time to run: " + lazyPeriod + "ms");
		System.out.println("Non-Lazy loading! Time to run: " + nonLazyPeriod
				+ "ms");
		if (lazyPeriod < nonLazyPeriod) {
			System.out.println("Lazy loading is faster.....WIN");
		} else {
			System.out.println("Non-Lazy loading is faster.....WIN");
		}
	}

}
